# -----------------------------------------------------------------------------#
# title:   Elite-Public Interaction on Twitter:  
#          EU issue Expansion in the Campaign
# content: code to reproduce Figure 1
# journal: European Journal of Political Research
#    year: 2020
# -----------------------------------------------------------------------------#
# for RStudio warnings
# !diagnostics off

# packages
library("dplyr")
library("ggplot2")
library("ggrepel")
library("firasans")
library("gridExtra")
library("scales")

Sys.setenv(TZ = "Europe/Berlin")

# --------------------------------------------------------------------------#
# a. data loading and recoding
# --------------------------------------------------------------------------#
load("cands-all.RData")


# get ranks
df <- mutate(cands_all, 
                 rank1 = rank(total_cands, ties.method = "first"),
                 rank2 = rank(cands_act_twitter/total_cands, ties.method = "first"),
                 rank3 = rank(med_tweets, ties.method = "first"),
                 rank4 = rank(total_responses, ties.method = "first"),
                 rank5 = rank(rat_resptw, ties.method = "first"),
                 rank6 = rank(med_responses/cands_act_twitter, ties.method = "first"))

df$labs_1 <- paste0("Candidates: ", df$total_cands, " (", df$rank1, "/27)",
                  "\nActive on Twitter: ", df$cands_act_twitter, " (", df$rank2, "/27)",
                  "\nMedian # tweets: ", round(df$med_tweets, 0), " (", df$rank3, "/27)")
df$labs_2 <- paste0("Mentions: ", df$total_responses, " (", df$rank4, "/27)",
                    "\nMentions/tweet: ", round(df$rat_resptw, 2), " (", df$rank5, "/27)",
                    "\nMentions/candidate: ", round(df$med_responses/df$cands_act_twitter, 2), " (", df$rank6, "/27)")

# --------------------------------------------------------------------------#
# b. plot candidates
# --------------------------------------------------------------------------#

p1 <- ggplot(df, aes(x = total_cands, y = cands_act_twitter/total_cands, label = ac,
               size = total_tweets)) +
  geom_vline(xintercept = median(df$total_cands), linetype = 2, alpha = 0.25) +
  geom_hline(yintercept = median(df$cands_act_twitter/df$total_cands),
             linetype = 2, alpha = 0.25) +
  ggrepel::geom_label_repel(data = filter(df, Country == "UK"), size = 3,
                            aes(label = labs_1),
                            hjust = 1.25, vjust = 0,
                            family = "Arial Narrow") +
  ggrepel::geom_label_repel(data = filter(df, Country == "Greece"), size = 3,
                            aes(label = labs_1),
                            hjust = 0.8, 
                            vjust = -0.85,
                            family = "Arial Narrow") +
  ggrepel::geom_label_repel(data = filter(df, Country == "Spain"), size = 3,
                            aes(label = labs_1),
                            hjust = 0.15, 
                            vjust = -0.5,
                            family = "Arial Narrow") +
  ggrepel::geom_label_repel(data = filter(df, Country == "Germany"), size = 3,
                            aes(label = labs_1),
                            hjust = -0.5, 
                            vjust = -2.25,
                            family = "Arial Narrow") +
  geom_point(aes(fill = as.factor(is_samp)), shape = 21) +
  geom_text(data = filter(df, is_samp == 0), colour = "black", size = 2) +
  geom_text(data = filter(df, is_samp == 1), aes(label = Country), colour = "white", size = 2) +
  scale_fill_manual("", values = c("0" = "grey70",
                                   "1" = "grey20"), guide = FALSE) +
  scale_size_continuous(range = c(6, 16), guide = FALSE) +
  ylim(0, 1) +
  scale_x_log10(breaks = trans_breaks("log10", function(x) 10^x),
                labels = trans_format("log10", math_format(10^.x))) +
  theme_ipsum_fsc(base_size = 12, grid = "") +
  theme(panel.background = element_rect(fill = "grey98", colour = NA)) +
  theme(strip.text = element_text(size = 16),
        axis.text.y = element_text(size = 14),
        axis.text.x = element_text(size = 12),
        panel.grid.major.y = element_line(colour = "grey90", size = 0.2, linetype = 2),
        panel.grid.major.x = element_line(colour = "grey90", size = 0.2, linetype = 2),
        panel.spacing = unit(1.5, "lines"),
        axis.title.x = element_text(size  = 10, hjust = 0, vjust = 0),
        axis.title.y = element_text(size  = 10, hjust = 1, vjust = 1, angle = 360),
        plot.margin = unit(c(1,1,1,1), "cm"),
        strip.text.y = element_text(angle = 360),
        plot.title = element_text(size = 14, face = "bold", hjust = 0.5),
        legend.position = c(0.9, 0.25),
        strip.background = element_rect(fil = "grey70", colour = "NA"),
        strip.text.x = element_text(hjust = 0.5, colour = "white")) +
  labs(x = "(log of) Number of candidates", y = "Proportion of candidates\nactive on Twitter", 
       title = "a. Comparative summary of candidates and their activity, 2014",
       caption = "Note: Median # tweets calculated based on active candidates. 
                  Active candidates had a Twitter account and sent at least one tweet in the campaign period.
                  Dashed lines for median values. In parentheses: country rank, from low to high. Size proportional to total tweets.")

p2 <- ggplot(df, aes(x = total_responses, y = rat_resptw, label = ac,
               size = med_responses/cands_act_twitter)) +
  geom_vline(xintercept = median(df$total_responses), linetype = 2, alpha = 0.25) +
  geom_hline(yintercept = median(df$rat_resptw),
             linetype = 2, alpha = 0.25) +
  ggrepel::geom_label_repel(data = filter(df, Country == "UK" | Country == "Spain"), size = 3,
                            aes(label = labs_2),
                            hjust = -0.25, 
                            vjust = -0.75,
                            family = "Arial Narrow") +
  ggrepel::geom_label_repel(data = filter(df, Country == "Greece" | Country == "Germany"), size = 3,
                            aes(label = labs_2),
                            hjust = -0.25, 
                            vjust = 0.75,
                            family = "Arial Narrow") +
  geom_point(aes(fill = as.factor(is_samp)), shape = 21) +
  geom_text(data = filter(df, is_samp == 0), colour = "black", size = 2) +
  geom_text(data = filter(df, is_samp == 1), aes(label = Country), colour = "white", size = 2) +
  scale_fill_manual("", values = c("0" = "grey70",
                                   "1" = "grey20"), guide = FALSE) +
  scale_size_continuous(range = c(6, 16), guide = FALSE) +
  scale_x_log10(breaks = trans_breaks("log10", function(x) 10^x),
                labels = trans_format("log10", math_format(10^.x))) +
  theme_ipsum_fsc(base_size = 12, grid = "") +
  theme(panel.background = element_rect(fill = "grey98", colour = NA)) +
  theme(strip.text = element_text(size = 16),
        axis.text.y = element_text(size = 14),
        axis.text.x = element_text(size = 12),
        panel.grid.major.y = element_line(colour = "grey90", size = 0.2, linetype = 2),
        panel.grid.major.x = element_line(colour = "grey90", size = 0.2, linetype = 2),
        panel.spacing = unit(1.5, "lines"),
        axis.title.x = element_text(size  = 10, hjust = 0, vjust = 0),
        axis.title.y = element_text(size  = 10, hjust = 1, vjust = 1, angle = 360),
        plot.margin = unit(c(1,1,1,1), "cm"),
        strip.text.y = element_text(angle = 360),
        plot.title = element_text(size = 14, face = "bold", hjust = 0.5),
        legend.position = c(0.9, 0.25),
        strip.background = element_rect(fil = "grey70", colour = "NA"),
        strip.text.x = element_text(hjust = 0.5, colour = "white")) +
  labs(x = "(log of) Total candidate mentions", y = "Median mentions\nper tweet", 
       title = "b. Comparative summary of candidate mentions, 2014",
       caption = "Note: Mentions of candidates by non-candidates, i.e. broader public.
       Size proportional to mentions/candidate (median), only active candidates included.
       Dashed lines for median values. In parentheses: country rank, from low to high.")

# occassional device error/warning can happen (for zoom)
# just re-run the code (if in RStudio)
p_both <- grid.arrange(p1, p2, ncol = 2) 
p_both

# --------------------------------------------------------------------------#
# Appendix. sessionInfo
# --------------------------------------------------------------------------#
# R version 3.5.2 (2018-12-20)
# Platform: x86_64-apple-darwin15.6.0 (64-bit)
# Running under: macOS  10.15.3
# 
# Matrix products: default
# BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
# LAPACK: /Library/Frameworks/R.framework/Versions/3.5/Resources/lib/libRlapack.dylib
# 
# locale:
#   [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
# 
# attached base packages:
#   [1] stats     graphics  grDevices utils     datasets  methods   base     
# 
# other attached packages:
#   [1] scales_1.1.0     gridExtra_2.3    firasans_0.1.0   hrbrthemes_0.7.2 ggrepel_0.8.0   
# [6] ggplot2_3.2.1    dplyr_0.8.3     
# 
# loaded via a namespace (and not attached):
#   [1] Rcpp_1.0.3        pillar_1.4.2      compiler_3.5.2    tools_3.5.2       extrafont_0.17   
# [6] digest_0.6.22     evaluate_0.14     lifecycle_0.1.0   tibble_2.1.3      gtable_0.3.0     
# [11] pkgconfig_2.0.3   rlang_0.4.1       rstudioapi_0.10   yaml_2.2.0        xfun_0.11        
# [16] Rttf2pt1_1.3.7    withr_2.1.2       knitr_1.25        gdtools_0.2.1     systemfonts_0.1.1
# [21] grid_3.5.2        tidyselect_0.2.5  glue_1.3.1        R6_2.4.1          rmarkdown_1.16   
# [26] farver_2.0.1      purrr_0.3.3       extrafontdb_1.0   magrittr_1.5      htmltools_0.4.0  
# [31] assertthat_0.2.1  colorspace_1.4-1  labeling_0.3      lazyeval_0.2.2    munsell_0.5.0    
# [36] crayon_1.3.4   
